﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Text.RegularExpressions;

namespace PMisuseAn.io
{
    public class GroupFunctionSerialisationEngine
    {
        static string activeDir = @"..\..\Database\GroupFunctionDB";
        
        static string newPath = "";
        static string newFileName = "";
        static string _clusterName = "";

        public static void serialise(string groupFunctionName,string clusterName, GroupFunctionDB groupFunctionDB)
        {
            if (!Directory.Exists(activeDir))
            {
                Directory.CreateDirectory(activeDir);
            }

            newPath = System.IO.Path.Combine(activeDir, clusterName);
            _clusterName = clusterName;
            if (!Directory.Exists(newPath))
            {
                Directory.CreateDirectory(newPath);
            }

            newFileName = groupFunctionName;
            newPath = System.IO.Path.Combine(newPath, newFileName);

            if (!File.Exists(newPath))
            {
                FileStream fs = null;
                try
                {
                    fs = File.Create(newPath);

                }
                finally
                {
                    fs.Dispose();
                    GC.Collect();
                    fs.Close();
                }                
            }

            Stream stream = null;
            try
            {
                stream = File.Open(newPath, FileMode.Create);
                BinaryFormatter bformatter = new BinaryFormatter();

                bformatter.Serialize(stream, groupFunctionDB);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Dispose();
                    stream.Close();
                }
            }           
        }

        public static GroupFunctionDB deSerialiseActorDB(string clusterName, string groupFunctionName)
        {
            if (!Directory.Exists(activeDir))
            {
                Directory.CreateDirectory(activeDir);
            }

            newPath = System.IO.Path.Combine(activeDir, clusterName);
            _clusterName = clusterName;
            newFileName =  groupFunctionName;
            string newPathx = System.IO.Path.Combine(newPath, newFileName);
            
            GroupFunctionDB groupFunctionDB = null;
            bool deserialised = false;
            int counter = 0;
            while (!deserialised && counter < 100)
            {
                Stream stream = null;
                try
                {
                    counter++;
                    stream = File.Open(newPathx, FileMode.Open, FileAccess.Read, FileShare.None);
                    BinaryFormatter bformatter = new BinaryFormatter();

                    groupFunctionDB = (GroupFunctionDB)bformatter.Deserialize(stream);
                    deserialised = true;
                }
                catch
                {
                    //If it cannot serialise catch 
                } 
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                        GC.Collect();
                        stream.Close();
                    }
                }
            }
            if (counter > 100)
                throw new Exception("Unable to deserialise file!");

            return groupFunctionDB;
        }

        public static void deleteGroupFunctionDB(string groupFunctionName, string clusterName)
        {
            string d_path = System.IO.Path.Combine(activeDir, clusterName);
            if (Directory.Exists(d_path))
            {
                string fd_Path = System.IO.Path.Combine(d_path, groupFunctionName);
                if (File.Exists(fd_Path))
                {
                    File.Delete(fd_Path);
                }
            }
        }

        public static List<string> getGroupFunctionList(string clusterName)
        {
            newPath = System.IO.Path.Combine(activeDir, clusterName);

            string[] gfNames = null;
            if (Directory.Exists(newPath))
            {
                gfNames = Directory.GetFiles(newPath);
            }
            List<string> gf_ns = new List<string>();
            if (gfNames != null)
            {
                foreach (string gfName in gfNames)
                {
                    string[] words = Regex.Split(gfName, @"\\");
                    string st = words[words.Count() - 1];
                    gf_ns.Add(st);
                }
            }

            return gf_ns;
        }

        
        public static int totalGroupFunctions()
        {
            newPath = System.IO.Path.Combine(activeDir, _clusterName);

            string[] interactionNames = null;
            if (Directory.Exists(newPath))
            {
                interactionNames = Directory.GetFiles(newPath);
                return interactionNames.Count();
            }

            return 0;
        }
    }
}

